﻿/* main.c */
#include "app_inc.h"

/*
* 在本例中，将PTB1引脚同PTE1相连，即LPSPI0的SIN引脚同SOUT引脚相连
* 用户在串口终端输入任一字符作为发送缓冲区初始值，之后程序通过SPI_EDMA通道发送出去
* SPM_EDMA接收通道接到数据保存到接收缓冲区中。比较两个缓冲区的值，判断传输过程是否打通。
*/

#define DEMO_LPSPI_EDMA_BUF_LEN 16U

uint8_t gAppLpspiTxBuf[DEMO_LPSPI_EDMA_BUF_LEN];
uint8_t gAppLpspiRxBuf[DEMO_LPSPI_EDMA_BUF_LEN];

LPSPI_EDMA_MasterXferHandler_T gAppLpspiEdmaXferHandle;
LPSPI_EDMA_MasterXferHandler_T * volatile gAppLpspiEdmaXferHandler = &gAppLpspiEdmaXferHandle;

LPSPI_EDMA_HwDev_T gAppLpspiEdmaHwDevStruct =
{
    .LpspiBase = LPSPI0,
    .EdmaLpspiTxChnIdx = 0U,
    .EdmaLpspiTxTriggerSource = eDMAMUX_TriggerSource_LPSPI0_Tx,
    .EdmaLpspiRxChnIdx = 1U,
    .EdmaLpspiRxTriggerSource = eDMAMUX_TriggerSource_LPSPI0_Rx,
    .EdmaRxChnIRQn = DMA1_IRQn /* 对应EdmaLpspiRxChnIdx */
};

LPSPI_MasterConfig_T gAppLpspiMasterConfigStruct =
{
    .enCSHigh = false,
    .TxFIFOWatermark = 1U,
    .RxFIFOWatermark = 0U
};

static void LPSPI_Configuration(void);
static void EDMA_Configuration(void);

volatile bool gAppXferDoneFlag = false;
void App_XferDoneCallback(void)
{
    gAppXferDoneFlag = true;
}

int main(void)
{
    //LPSPI_XferCommand_T lpspiXferCommandStruct;
    volatile uint32_t tmp32;
    uint8_t ch;
    uint32_t i;

    BSP_InitSystem();
    BSP_InitStdioLPUART(115200U);

    printf("\r\n\r\nLPSPI_MPU9250 Example.\r\n");
    printf("Compiled on %s, %s\r\n\r\n", __DATE__, __TIME__);

    LPSPI_Configuration();
    EDMA_Configuration();

    LPSPI_EDMA_MasterInit(gAppLpspiEdmaXferHandler,
        &gAppLpspiEdmaHwDevStruct,
        &gAppLpspiMasterConfigStruct );

    while (1)
    {
        printf("Press any key test the xfer.\r\n");
        ch = getchar();

        /* 准备缓冲区 */
        for (i = 0U; i < DEMO_LPSPI_EDMA_BUF_LEN; i++)
        {
            gAppLpspiTxBuf[i] = ch; /* 填充发送缓冲区 */
            gAppLpspiRxBuf[i] = 0U; /* 清空接收缓冲区 */
        }

        /* 启动传输 */
        gAppXferDoneFlag = false;
        LPSPI_EDMA_StartMasterXfer(
            gAppLpspiEdmaXferHandler,
            gAppLpspiTxBuf, gAppLpspiRxBuf, DEMO_LPSPI_EDMA_BUF_LEN,
            App_XferDoneCallback );

        /* 等待传输完成 */
        while (!gAppXferDoneFlag)
        {}

        for (i = 0U; i < DEMO_LPSPI_EDMA_BUF_LEN; i++)
        {
            if (gAppLpspiTxBuf[i] != gAppLpspiRxBuf[i])
            {
                gAppXferDoneFlag = false; /* 临时使用gAppXferDoneFlag作为判断匹配标志位 */
            }
        }

        if (gAppXferDoneFlag)
        {
            printf("Xfer Succeed.\r\n");
        }
        else
        {
            printf("Xfer Failed with unmatched value.\r\n");
        }

        printf("\r\n");
    }
}

static void LPSPI_Configuration(void)
{
    // LPSPI_MasterConfig_T lpspiMasterConfigStruct;

    /* Enable clock. */
    PCC->CLKCFG[PCC_LPSPI0_INDEX] = PCC_CLKCFG_CGC_MASK | PCC_CLKCFG_PCS(6U);
    PCC->CLKCFG[PCC_PORTB_INDEX] = PCC_CLKCFG_CGC_MASK;
    PCC->CLKCFG[PCC_PORTE_INDEX] = PCC_CLKCFG_CGC_MASK;

    /* Pin mux. */
    PORTB->PCR[0] = PORT_PCR_MUX(3); /* LPSPI0_PCS0. */
    PORTB->PCR[1] = PORT_PCR_MUX(3); /* LPSPI0_SOUT. */
    PORTE->PCR[0] = PORT_PCR_MUX(2); /* LPSPI0_SCLK. */
    PORTE->PCR[1] = PORT_PCR_MUX(2); /* LPSPI0_SIN. */

    /* LPSPI. */
    LPSPI_HAL_Reset(LPSPI0);
    LPSPI_HAL_Enable(LPSPI0, true);

#if 0 /* 在LPSPI_EDMA的初始化过程中将对LPSPI的硬件进行配置 */
    lpspiMasterConfigStruct.enCSHigh = false;
    lpspiMasterConfigStruct.TxFIFOWatermark = 1U;
    lpspiMasterConfigStruct.RxFIFOWatermark = 0U;
    LPSPI_HAL_ConfigMaster(LPSPI0, &lpspiMasterConfigStruct);
#endif
}

static void EDMA_Configuration(void)
{
    /* 开时钟 */
    PCC->CLKCFG[PCC_DMA0_INDEX] = PCC_CLKCFG_CGC_MASK;
    PCC->CLKCFG[PCC_DMAMUX0_INDEX] = PCC_CLKCFG_CGC_MASK;
    
    /* 复位EDMA模块 */
    EDMA_HAL_ResetEngine();
}

/* DMA1为接收完成中断 */
void DMA1_IRQHandler(void)
{
    LPSPI_EDMA_MasterXferIRQHandler(gAppLpspiEdmaXferHandler);
}

/* EOF. */

